package sg.edu.nus.iss.billing.datastore;

import java.io.File;
import java.io.IOException;

import sg.edu.nus.iss.billing.datastore.impl.FileDataStoreImpl;
import sg.edu.nus.iss.billing.datastore.impl.SerializeStorage;
import sg.edu.nus.iss.billing.datastore.impl.TSupportFileDataStoreImpl;

/**
 * Data base factory, for switching different implementations of IDataStore
 * 
 * @author Wang DaYong
 *
 */
public class DBFactory {

	private static final String PATH_SEP = System.getProperty("file.separator");
	
	private static final String STORE_FOLER = "data";
	
	public static final String TEST_STORE_FOLER = STORE_FOLER.concat(PATH_SEP).concat("junitdata");

	private static DBFactory instance;

	private static String storeFolder;

	static {
		try {
			storeFolder = (new File(".").getCanonicalPath().concat(PATH_SEP).concat(STORE_FOLER).concat(PATH_SEP));
		} catch (IOException e) {
			// this exception should not happen
			System.err.println(e);
		}
	}

	private DBFactory() {

	}

	/**
	 * Get the instance of DBFactory, will not consider multi-thread
	 * @return
	 */
	public static DBFactory instance() {

		if (instance==null) {
			instance = new DBFactory();
		}
		return instance;
	}

	/**
	 * Get an instance of IDataStore which is using SerializeStorage as the way of storage/parse to/from data file
	 * and this instance will not support transaction
	 * @return IDataStore
	 */
	public IDataStore getSDStore() {

		AbstractFileStorage storage = new SerializeStorage(storeFolder);
		return new FileDataStoreImpl(storage);
	}

	/**
	 * Get an instance of IDataStore which is using SerializeStorage as the way of storage/parse to/from data file
	 * This instance support transaction
	 * @return IDataStore
	 */
	public IDataStore getTSupportDataStore() {

		AbstractFileStorage storage = new SerializeStorage(storeFolder);
		return new TSupportFileDataStoreImpl(storage);
	}

	/**
	 * Get an instance of IDataStore which is using SerializeStorage as the way of storage/parse to/from data file
	 * This instance support transaction
	 * 
	 * @param isCacheOn set cache on/off
	 * @param instantFlush set flush instantly on/off
	 * @return IDataStore
	 */
	public IDataStore getTSupportDataStore(boolean isCacheOn, boolean instantFlush) {

		AbstractFileStorage storage = new SerializeStorage(storeFolder);
		storage.setInstantFlush(instantFlush);
		storage.configCache(isCacheOn);
		return new TSupportFileDataStoreImpl(storage);
	}
	
	/**
	 * This is just for Junit testing
	 * @param path
	 */
	@Deprecated
	public void setStoragePath(String path){
		try {
			storeFolder = (new File(".").getCanonicalPath().concat(PATH_SEP).concat(path).concat(PATH_SEP));
		} catch (IOException e) {
			// this exception should not happen
			System.err.println(e);
		}
	}
}
